gusucode.com > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序 > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序/code/Explorer/CJToolBarBase.cpp
// CJToolBarBase.cpp : implementation file // Copyright ? 1998-1999 CodeJock.com, All Rights Reserved. // See ReadMe.txt for TERMS OF USE. // // Copied from MFC, Visual C++ 6, to extend functionality to Visual C++ 5 // users, with some ideas taken from Luis Barreira's article 'Classes for new IE4 controls' // http://www.codeguru.com/controls/ie4_controls_classes.shtml // ///////////////////////////////////////////////////////////////////////////// /**************************************************************************** * * $Date: 8/31/99 1:11a $ * $Revision: 5 $ * $Archive: /CodeJockey/CJLibrary/CJToolBarBase.cpp $ * * $History: CJToolBarBase.cpp $ * * ***************** Version 5 ***************** * User: Kirk Stowell Date: 8/31/99 Time: 1:11a * Updated in $/CodeJockey/CJLibrary * Updated copyright and contact information. * * ***************** Version 4 ***************** * User: Kirk Stowell Date: 7/28/99 Time: 12:38a * Updated in $/CodeJockey/CJLibrary * Final pass for release 6.08. * * ***************** Version 3 ***************** * User: Kirk Stowell Date: 7/25/99 Time: 12:30a * Updated in $/CodeJockey/CJLibrary * * ***************** Version 2 ***************** * User: Kirk Stowell Date: 6/23/99 Time: 12:33a * Updated in $/CodeJockey/CJLibrary * * ***************** Version 1 ***************** * User: Kirk Stowell Date: 7/14/99 Time: 10:29p * Created in $/CodeJockey/CJLibrary * Copied from MFC v6 and techno preview for v5. Added to extend * functionality to Visual C++ 5.0 users. * ***************************************************************************/ #include "stdafx.h" #include "CJToolBarBase.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCJToolBarBase CCJToolBarBase::CCJToolBarBase() { m_bInReBar = false; m_bExStyle = false; } CCJToolBarBase::~CCJToolBarBase() { } BEGIN_MESSAGE_MAP(CCJToolBarBase, CControlBar) //{{AFX_MSG_MAP(CCJToolBarBase) ON_WM_PAINT() ON_WM_WINDOWPOSCHANGING() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CCJToolBarBase::SetBorders(int cxLeft, int cyTop, int cxRight, int cyBottom) { ASSERT(cxLeft >= 0); ASSERT(cyTop >= 0); ASSERT(cxRight >= 0); ASSERT(cyBottom >= 0); m_cxLeftBorder = cxLeft; m_cyTopBorder = cyTop; m_cxRightBorder = cxRight; m_cyBottomBorder = cyBottom; } LRESULT CCJToolBarBase::WindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam) { ASSERT_VALID(this); LRESULT lResult; switch (nMsg) { case WM_NOTIFY: case WM_COMMAND: case WM_DRAWITEM: case WM_MEASUREITEM: case WM_DELETEITEM: case WM_COMPAREITEM: case WM_VKEYTOITEM: case WM_CHARTOITEM: // send these messages to the owner if not handled if (OnWndMsg(nMsg, wParam, lParam, &lResult)) return lResult; else { // try owner next lResult = GetOwner()->SendMessage(nMsg, wParam, lParam); // special case for TTN_NEEDTEXTA and TTN_NEEDTEXTW if(nMsg == WM_NOTIFY) { NMHDR* pNMHDR = (NMHDR*)lParam; if (pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW) { TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; if ((pNMHDR->code == TTN_NEEDTEXTA && (!pTTTA->lpszText || !*pTTTA->lpszText)) || (pNMHDR->code == TTN_NEEDTEXTW && (!pTTTW->lpszText || !*pTTTW->lpszText))) { // not handled by owner, so let bar itself handle it lResult = CWnd::WindowProc(nMsg, wParam, lParam); } } } return lResult; } } // otherwise, just handle in default way lResult = CWnd::WindowProc(nMsg, wParam, lParam); return lResult; } void CCJToolBarBase::OnWindowPosChanging(LPWINDOWPOS lpWndPos) { // WINBUG: We call DefWindowProc here instead of CWnd::OnWindowPosChanging // (which calls CWnd::Default, which calls through the super wndproc) // because certain control bars that are system implemented (such as // CToolBar with TBSTYLE_FLAT) do not implement WM_WINDOWPOSCHANGING // correctly, causing repaint problems. This code bypasses that whole // mess. ::DefWindowProc(m_hWnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)lpWndPos); if (lpWndPos->flags & SWP_NOSIZE) return; // invalidate borders on the right CRect rect; GetWindowRect(&rect); CSize sizePrev = rect.Size(); int cx = lpWndPos->cx; int cy = lpWndPos->cy; if (cx != sizePrev.cx && (m_dwStyle & CBRS_BORDER_RIGHT)) { rect.SetRect(cx-afxData.cxBorder2, 0, cx, cy); InvalidateRect(&rect); rect.SetRect(sizePrev.cx-afxData.cxBorder2, 0, sizePrev.cx, cy); InvalidateRect(&rect); } // invalidate borders on the bottom if (cy != sizePrev.cy && (m_dwStyle & CBRS_BORDER_BOTTOM)) { rect.SetRect(0, cy-afxData.cyBorder2, cx, cy); InvalidateRect(&rect); rect.SetRect(0, sizePrev.cy-afxData.cyBorder2, cx, sizePrev.cy); InvalidateRect(&rect); } } void CCJToolBarBase::OnPaint() { // background is already filled in gray CPaintDC dc(this); // erase background now if (IsVisible()) DoPaint(&dc); // delegate to paint helper } void CCJToolBarBase::EraseNonClient() { // get window DC that is clipped to the non-client area CWindowDC dc(this); CRect rectClient; GetClientRect(rectClient); CRect rectWindow; GetWindowRect(rectWindow); ScreenToClient(rectWindow); rectClient.OffsetRect(-rectWindow.left, -rectWindow.top); dc.ExcludeClipRect(rectClient); // draw borders in non-client area rectWindow.OffsetRect(-rectWindow.left, -rectWindow.top); DrawBorders(&dc, rectWindow); // erase parts not drawn dc.IntersectClipRect(rectWindow); SendMessage(WM_ERASEBKGND, (WPARAM)dc.m_hDC); // draw gripper in non-client area DrawGripper(&dc, rectWindow); } void CCJToolBarBase::DoPaint(CDC* pDC) { ASSERT_VALID(this); ASSERT_VALID(pDC); // paint inside client area CRect rect; GetClientRect(rect); DrawBorders(pDC, rect); DrawGripper(pDC, rect); } void CCJToolBarBase::DrawBorders(CDC* pDC, CRect& rect) { ASSERT_VALID(this); ASSERT_VALID(pDC); DWORD dwStyle = m_dwStyle; if (!(dwStyle & CBRS_BORDER_ANY)) return; // prepare for dark lines ASSERT(rect.top == 0 && rect.left == 0); if(m_bInReBar) { CRect rect1, rect2; rect1 = rect; rect2 = rect; COLORREF clr = afxData.bWin4 ? afxData.clrBtnShadow : afxData.clrWindowFrame; // draw dark line one pixel back/up if (dwStyle & CBRS_BORDER_3D) { rect1.right -= CX_BORDER; rect1.bottom -= CY_BORDER; } if (dwStyle & CBRS_BORDER_TOP) rect2.top += afxData.cyBorder2; if (dwStyle & CBRS_BORDER_BOTTOM) rect2.bottom -= afxData.cyBorder2; // draw left and top if (dwStyle & CBRS_BORDER_LEFT) pDC->FillSolidRect(0, rect2.top, CX_BORDER, rect2.Height(), clr); if (dwStyle & CBRS_BORDER_TOP) pDC->FillSolidRect(0, 0, rect.right, CY_BORDER, clr); // draw right and bottom if (dwStyle & CBRS_BORDER_RIGHT) pDC->FillSolidRect(rect1.right, rect2.top, -CX_BORDER, rect2.Height(), clr); if (dwStyle & CBRS_BORDER_BOTTOM) pDC->FillSolidRect(0, rect1.bottom, rect.right, -CY_BORDER, clr); if (dwStyle & CBRS_BORDER_3D) { // prepare for hilite lines clr = afxData.clrBtnHilite; // draw left and top if (dwStyle & CBRS_BORDER_LEFT) pDC->FillSolidRect(1, rect2.top, CX_BORDER, rect2.Height(), clr); if (dwStyle & CBRS_BORDER_TOP) pDC->FillSolidRect(0, 1, rect.right, CY_BORDER, clr); // draw right and bottom if (dwStyle & CBRS_BORDER_RIGHT) pDC->FillSolidRect(rect.right, rect2.top, -CX_BORDER, rect2.Height(), clr); if (dwStyle & CBRS_BORDER_BOTTOM) pDC->FillSolidRect(0, rect.bottom, rect.right, -CY_BORDER, clr); } if (dwStyle & CBRS_BORDER_LEFT) rect.left += afxData.cxBorder2; if (dwStyle & CBRS_BORDER_TOP) rect.top += afxData.cyBorder2; if (dwStyle & CBRS_BORDER_RIGHT) rect.right -= afxData.cxBorder2; if (dwStyle & CBRS_BORDER_BOTTOM) rect.bottom -= afxData.cyBorder2; } else { if(dwStyle & CBRS_BORDER_RIGHT) { pDC->FillSolidRect(rect.right-1, 0, rect.right, rect.bottom, afxData.clrBtnShadow); rect.right--; } if(dwStyle & CBRS_BORDER_BOTTOM) { pDC->FillSolidRect(0, rect.bottom-1, rect.right, rect.bottom, afxData.clrBtnShadow); rect.bottom--; } if(dwStyle & CBRS_BORDER_TOP) { pDC->FillSolidRect(0, 0, rect.right, 1, afxData.clrBtnHilite); rect.top++; } if(dwStyle & CBRS_BORDER_LEFT) { pDC->FillSolidRect(0, 0, 1, rect.bottom, afxData.clrBtnHilite); rect.left++; } } } #define CX_GRIPPER 3 #define CY_GRIPPER 3 #define CX_BORDER_GRIPPER 2 #define CY_BORDER_GRIPPER 2 void CCJToolBarBase::DrawGripper(CDC* pDC, const CRect& rect) { // if we are floating return. if( m_dwStyle & CBRS_FLOATING ) { return; } // if we are to draw the extended "office" style gripper. if(( m_dwStyle & CBRS_GRIPPER ) && ( m_bExStyle == true )) { // draw the gripper in the border if (m_dwStyle & CBRS_ORIENT_HORZ) { // Draw the first gripper. pDC->Draw3dRect( rect.left+3, rect.top+2, 3, rect.Height()-4, afxData.clrBtnHilite, afxData.clrBtnShadow); pDC->SetPixel( rect.left+3, rect.top+2+rect.Height()-5, afxData.clrBtnHilite); // Draw the second gripper. pDC->Draw3dRect( rect.left+6, rect.top+2, 3, rect.Height()-4, afxData.clrBtnHilite, afxData.clrBtnShadow); pDC->SetPixel( rect.left+6, rect.top+2+rect.Height()-5, afxData.clrBtnHilite); } else { // Draw the first gripper. pDC->Draw3dRect( rect.left+2, rect.top+3, rect.Width()-4, 3, afxData.clrBtnHilite, afxData.clrBtnShadow); pDC->SetPixel( rect.left+2+rect.Width()-5, rect.top+3, afxData.clrBtnHilite); // Draw the second gripper. pDC->Draw3dRect( rect.left+2, rect.top+6, rect.Width()-4, 3, afxData.clrBtnHilite, afxData.clrBtnShadow); pDC->SetPixel( rect.left+2+rect.Width()-5, rect.top+6, afxData.clrBtnHilite); } GdiFlush(); } // if we are to draw the "ReBar" style gripper. else if(( m_dwStyle & CBRS_GRIPPER ) && ( m_bInReBar == true )) { // draw the gripper in the border if (m_dwStyle & CBRS_ORIENT_HORZ) { // Draw the first gripper. pDC->Draw3dRect( rect.left+CX_BORDER_GRIPPER, rect.top+m_cyTopBorder, CX_GRIPPER, rect.Height()-m_cyTopBorder-m_cyBottomBorder, afxData.clrBtnHilite, afxData.clrBtnShadow); } else { // Draw the first gripper. pDC->Draw3dRect( rect.left+m_cyTopBorder, rect.top+CY_BORDER_GRIPPER, rect.Width()-m_cyTopBorder-m_cyBottomBorder, CY_GRIPPER, afxData.clrBtnHilite, afxData.clrBtnShadow); } GdiFlush(); } // by default, we will draw the "visual studio" style gripper. else if( m_dwStyle & CBRS_GRIPPER ) { // draw the gripper in the border if (m_dwStyle & CBRS_ORIENT_HORZ) { // Draw the first gripper. pDC->Draw3dRect( rect.left+1, rect.top+2, 3, rect.Height()-4, afxData.clrBtnHilite, afxData.clrBtnShadow); // Draw the second gripper. pDC->Draw3dRect( rect.left+5, rect.top+2, 3, rect.Height()-4, afxData.clrBtnHilite, afxData.clrBtnShadow); } else { // Draw the first gripper. pDC->Draw3dRect( rect.left+2, rect.top+1, rect.Width()-4, 3, afxData.clrBtnHilite, afxData.clrBtnShadow); // Draw the second gripper. pDC->Draw3dRect( rect.left+2, rect.top+5, rect.Width()-4, 3, afxData.clrBtnHilite, afxData.clrBtnShadow); } GdiFlush(); } } // input CRect should be client rectangle size void CCJToolBarBase::CalcInsideRect(CRect& rect, BOOL bHorz) const { ASSERT_VALID(this); DWORD dwStyle = m_dwStyle; if (dwStyle & CBRS_BORDER_LEFT) rect.left += afxData.cxBorder2; if (dwStyle & CBRS_BORDER_TOP) rect.top += afxData.cyBorder2; if (dwStyle & CBRS_BORDER_RIGHT) rect.right -= afxData.cxBorder2; if (dwStyle & CBRS_BORDER_BOTTOM) rect.bottom -= afxData.cyBorder2; // inset the top and bottom. if (bHorz) { rect.left += m_cxLeftBorder; rect.top += m_cyTopBorder; rect.right -= m_cxRightBorder; rect.bottom -= m_cyBottomBorder; if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER) { rect.left += CX_BORDER_GRIPPER+CX_GRIPPER+CX_BORDER_GRIPPER; if( m_bExStyle == true ) { rect.left += CX_GRIPPER; } if(( m_bExStyle == false ) && ( m_bInReBar == false )) { rect.left -= CX_BORDER_GRIPPER+CX_GRIPPER; } } } else { rect.left += m_cyTopBorder; rect.top += m_cxLeftBorder; rect.right -= m_cyBottomBorder; rect.bottom -= m_cxRightBorder; if ((m_dwStyle & (CBRS_GRIPPER|CBRS_FLOATING)) == CBRS_GRIPPER) { rect.top += CY_BORDER_GRIPPER+CY_GRIPPER+CY_BORDER_GRIPPER; if( m_bExStyle == true ) { rect.top += CY_GRIPPER; } if(( m_bExStyle == false ) && ( m_bInReBar == false )) { rect.top -= CY_BORDER_GRIPPER+CY_GRIPPER; } } } } ///////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CCJToolBarBase, CControlBar) /////////////////////////////////////////////////////////////////////////////